﻿using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Input;
using System.Net.Http;
using Windows.Storage.Streams;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI.Xaml.Controls;
//using Windows.UI.Popups;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls.Primitives;
using Svga.Annotations;
using System.Diagnostics;
using Windows.UI.Xaml.Navigation;
using System.Runtime.InteropServices;

namespace Svga
{
  public sealed partial class MainPage : Page, INotifyPropertyChanged
  {
    const string DllName = "GetGpuType";
    [DllImport(DllName)]//, CallingConvention = CallingConvention.StdCall
    public static extern IntPtr get_gpu_type();
    private int SpriteCount => 0;
    private int TotalFrame => this.Player?.TotalFrame ?? 0;
    private int TotalFrameForSlider => this.TotalFrame == 0 ? 0 : this.TotalFrame - 1;
    public MainPage()
    {
      this.InitializeComponent();
      this.init();
    }
    private bool _isShowDoneText;
    private bool IsShowDoneText
    {
      get => this._isShowDoneText;
      set
      {
        this._isShowDoneText = value;
        this.Notify(nameof(this.IsShowDoneText));
      }
    }
    private async void init()
    {
      var gpuText = await LoadGpuType();
      this.Player.GpuText = gpuText;
    }
    private async Task<string> LoadGpuType()
    {
      var fileName = "gpu.txt";
      var _localFolder = ApplicationData.Current.LocalFolder;
      try
      {
        var file = await _localFolder.GetFileAsync(fileName);
        var gpuType = await FileIO.ReadTextAsync(file);
        return gpuType;
      }
      catch (FileNotFoundException)
      {
        IntPtr gpuPtr = get_gpu_type();
        var gpuType = Marshal.PtrToStringAnsi(gpuPtr);
        var file = await _localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
        await FileIO.WriteTextAsync(file, gpuType);
        return gpuType;
      }
    }
    private void OnDragEnter(object sender, DragEventArgs e)
    {
      // 设置拖拽文件的可接受操作（如复制、移动等）
      e.AcceptedOperation = DataPackageOperation.Copy;
      e.DragUIOverride.Caption = "Drop file here";
      e.DragUIOverride.IsCaptionVisible = true;
      e.DragUIOverride.IsContentVisible = false;
      e.DragUIOverride.IsGlyphVisible = false;
      // 取消显示禁止图标
      e.Handled = true;
    }
    private async void OnDrop(object sender, DragEventArgs e)
    {
      var defer = e.GetDeferral();
      try
      {
        // 判断拖拽的数据是否包含文件
        if (e.DataView.Contains(StandardDataFormats.StorageItems))
        {
          // 获取拖拽的文件列表
          var items = await e.DataView.GetStorageItemsAsync();

          // 处理每个拖拽的文件
          //foreach (StorageFile file in items)
          if (items.Count > 0)
          {
            var file = items[0] as StorageFile;
            // 从 StorageFile 获取文件 Stream
            this.IsShowDoneText = false;
            using (var stream = await file.OpenAsync(FileAccessMode.Read, StorageOpenOptions.AllowOnlyReaders))
            {
              var player = this.Player;
              player.UnloadStage();
              player.LoadSvgaFileData(stream.AsStream());
              player.InitStage();
              player.Play();
            }

            this.Notify(nameof(this.SpriteCount));
            this.Notify(nameof(this.TotalFrame));
            this.Notify(nameof(this.TotalFrameForSlider));
          }
        }
      }
      finally
      {
        defer.Complete();
      }
    }
    private async Task<Stream> GetStreamFromUrlAsync(string url)
    {
      using (HttpClient client = new HttpClient())
      {
        // 发送HTTP请求并获取响应
        HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);

        // 检查响应是否成功
        if (response.IsSuccessStatusCode)
        {
          // 获取响应的内容作为流
          var buffer = await response.Content.ReadAsByteArrayAsync();
          var memoryStream = new InMemoryRandomAccessStream();
          await memoryStream.WriteAsync(buffer.AsBuffer());
          return memoryStream.AsStream();
        }
        else
        {
          // 如果响应失败，返回null
          return null;
        }
      }
    }
    private async void OnGetSvgaFromRemote(object sender, RoutedEventArgs e)
    {
      var url = SvgaUrl.Text;
      if (url != null && url.StartsWith("http"))
      {
        try
        {
          this.IsShowDoneText = false;
          using (var stream = await GetStreamFromUrlAsync(url))
          {
            if (stream != null)
            {
              var player = this.Player;
              player.UnloadStage();
              player.LoadSvgaFileData(stream);
              player.InitStage();
              player.Play();
            }
          }
        }
        catch (Exception ex)
        {
          Debug.WriteLine($"请求错误：\n{ex.Message}");
        }
        this.Notify(nameof(this.SpriteCount));
        this.Notify(nameof(this.TotalFrame));
        this.Notify(nameof(this.TotalFrameForSlider));
      }
      else
      {
        SvgaUrl.Text = "链接错误!";
        SolidColorBrush redBrush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
        SvgaUrl.Foreground = redBrush;
      }
    }
    private async void SelectFileAndInitPlayer()
    {
      var picker = new FileOpenPicker
      {
        ViewMode = PickerViewMode.List,
        SuggestedStartLocation = PickerLocationId.Desktop
      };
      picker.FileTypeFilter.Add(".svga");

      var file = await picker.PickSingleFileAsync();
      if (file == null)
      {
        return;
      }

      this.IsShowDoneText = false;
      using (var stream = await file.OpenAsync(FileAccessMode.Read, StorageOpenOptions.AllowOnlyReaders))
      {
        var player = this.Player;
        player.UnloadStage();
        player.LoadSvgaFileData(stream.AsStream());
        player.InitStage();
        player.Play();
      }

      this.Notify(nameof(this.SpriteCount));
      this.Notify(nameof(this.TotalFrame));
      this.Notify(nameof(this.TotalFrameForSlider));
    }

    private void StageOnLoop()
    {

    }
    private void OnRightTapped(object sender, RightTappedRoutedEventArgs e)//async 
    {
      // 创建上下文菜单
      var contextMenu = new MenuFlyout();

      // 创建菜单项
      var menuCopy = new MenuFlyoutItem { Text = "Copy Mp4 File" };

      // 为菜单项添加点击事件
      menuCopy.Click += OpenLocalFolderAndCopyDataAsync;

      // 将菜单项添加到上下文菜单中
      contextMenu.Items.Add(menuCopy);

      // 在元素的位置显示上下文菜单
      contextMenu.ShowAt(sender as FrameworkElement, e.GetPosition(sender as FrameworkElement));
    }
    private async void OpenLocalFolderAndCopyDataAsync(object sender, RoutedEventArgs e)
    {
      try
      {
        // 创建一个 FolderPicker 对象
        FolderPicker folderPicker = new FolderPicker
        {
          ViewMode = PickerViewMode.List,
          SuggestedStartLocation = PickerLocationId.Desktop,
        };
        folderPicker.FileTypeFilter.Add("*");

        // 让用户选择一个文件夹
        StorageFolder pickedFolder = await folderPicker.PickSingleFolderAsync();

        if (pickedFolder != null)
        {
          // 获取应用程序的本地数据文件夹
          StorageFolder localFolder = ApplicationData.Current.LocalFolder;
          var file = await localFolder.GetFileAsync("output.mp4");
          await file.MoveAsync(pickedFolder, file.Name, NameCollisionOption.ReplaceExisting);
          // 获取本地文件夹中的所有文件
          /*var files = await localFolder.GetFilesAsync();

          // 复制文件到用户选择的文件夹
          foreach (var file in files)
          {
            if (file.Name.EndsWith(".mp4"))
            {
              await file.MoveAsync(pickedFolder, file.Name, NameCollisionOption.ReplaceExisting);
            }
          }*/
        }
      }
      catch (Exception ex)
      {
        Debug.WriteLine($"打开窗口错误：\n{ex.Message}");
      }
    }
    private void OnChangeToggle(object sender, RoutedEventArgs e)
    {
      ToggleSwitch toggleSwitch = sender as ToggleSwitch;
      if (toggleSwitch != null)
      {
        if (toggleSwitch.IsOn == true)
        {
          //Debug.WriteLine("打开");
          this.Player.LoopCount = 1;
        }
        else
        {
          //Debug.WriteLine("关闭");
          this.Player.LoopCount = 0;
        }
      }
      this.Player.Pause();
      this.Notify(nameof(this.Player));
    }
    private void OnSelectFileClick(object sender, RoutedEventArgs e)
    {
      this.SelectFileAndInitPlayer();
    }

    private void OnPlayClick(object sender, RoutedEventArgs e)
    {
      this.Player.Play();
    }

    private void OnPauseClick(object sender, RoutedEventArgs e)
    {
      this.Player.Pause();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    private void Notify([CallerMemberName] string propertyName = null)
    {
      this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private void OnValueChanged(object sender, RangeBaseValueChangedEventArgs e)
    {
      if (sender is Slider slider && slider.FocusState != FocusState.Unfocused)
      {
        this.Player.Seek((int)e.NewValue);
      }
    }

    /*private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
      ComboBox comboBox = (ComboBox)sender;
      ComboBoxItem selectedItem = (ComboBoxItem)comboBox.SelectedItem;
      var selectedOption = selectedItem.Content.ToString();
      if (this.Player != null)
      {
        this.Player.GpuText = selectedOption;
      }
    }*/
    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
      base.OnNavigatedTo(e);
      if (e.Parameter is StorageFile file)
      {
        try
        {
          //this.IsShowDoneText = false;
          var player = this.Player;
          player.UnloadStage();
          using (var stream = await file.OpenAsync(FileAccessMode.Read, StorageOpenOptions.AllowOnlyReaders))
          {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>
            {
              player.LoadSvgaFileData(stream.AsStream());
              player.InitStage();
              player.Play();
            });
          }
          this.Notify(nameof(this.SpriteCount));
          this.Notify(nameof(this.TotalFrame));
          this.Notify(nameof(this.TotalFrameForSlider));
        }
        catch (Exception ex)
        {
          Debug.WriteLine($"关联文件错误：\n{ex.Message}");
        }
      }
    }
  }
}
